
import 'dart:convert';

import 'package:elevator/mqtt/mqtt_call_back.dart';
import 'package:flutter/cupertino.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:typed_data/typed_data.dart' as typed;

import 'constant.dart';

enum ConnectState {
  connectting,
  connected,
  disconnected,
}
//https://blog.csdn.net/WangQingLei0307/article/details/126744159

class MQTTManager{

  MQTTManager._internal();

  factory MQTTManager() => _instance;

  static late final MQTTManager _instance = MQTTManager._internal();

  late MqttServerClient mqttClient;

  late MqttCallBack callBack;

  late String clentId;

  ConnectState connectSate = ConnectState.disconnected;

  // final String MQTT_SERVER_HOST = "830819z48w.zicp.fun";
  // final String MQTT_IDENTIFIER = "flutter_client";
  // final int MQTT_PORT = 57020;
  // final String MQTT_USER = "admin";
  // final String MQTT_PASSWORD = "adminemqx123";


  Future<MqttServerClient> connect() async {
    mqttClient =
        MqttServerClient.withPort(Constant.MQTT_SERVER_HOST, clentId, Constant.MQTT_PORT);
    mqttClient.logging(on: false);
    mqttClient.onConnected = onConnected;
    mqttClient.onDisconnected = onDisconnected;
    mqttClient.onUnsubscribed = onUnsubscribed;
    mqttClient.onSubscribed = onSubscribed;
    mqttClient.onSubscribeFail = onSubscribeFail;
    mqttClient.pongCallback = pong;

    //设置心跳
    mqttClient.keepAlivePeriod = 60;
    // 设置自动重连和重连时间间隔
    mqttClient.autoReconnect = true;
    // 注册onAutoReconnect回调函数
    mqttClient.onAutoReconnect = () {
        dPrint('重新连接到MQTT代理...${mqttClient.connectionStatus!.state}');
        //connectSate = ConnectState.connectting;
        //mqttClient.connect();
    };

    final connMessage = MqttConnectMessage()
        .authenticateAs(Constant.MQTT_USER, Constant.MQTT_PASSWORD)
        .startClean()
        .withWillQos(MqttQos.atLeastOnce);
    mqttClient.connectionMessage = connMessage;

    //SSL
    mqttClient.secure = false;
    mqttClient.onBadCertificate = (dynamic a) => true;

    try {
      connectSate = ConnectState.connectting;
      await mqttClient.connect();
    } catch (e) {
      dPrint('Exception: $e');
      connectSate = ConnectState.disconnected;
      mqttClient.disconnect();
    }

    mqttClient.updates?.listen((List<MqttReceivedMessage<MqttMessage>> c) {
      final MqttPublishMessage message = c[0].payload as MqttPublishMessage;
      final payload =
        MqttPublishPayload.bytesToStringAsString(message.payload.message);

      dPrint('Received message:$payload from topic: ${c[0].topic}>');
      if(null != callBack){
        callBack.onMessageed(c[0].topic,message.payload.message);
      }
    });

    return mqttClient;
  }

  void disConnect(){
    mqttClient.disconnect();
  }

  Subscription? subscribe(String topic, MqttQos qosLevel){
    if (mqttClient.connectionStatus!.state != MqttConnectionState.connected) {
      return null;
    }
    return mqttClient.subscribe(topic, qosLevel);
  }

  int publishMessage(String pTopic, String msg) {
    typed.Uint8Buffer uint8buffer = typed.Uint8Buffer();
    var codeUnits = msg.codeUnits;
    uint8buffer.addAll(codeUnits);
    return mqttClient.publishMessage(pTopic, MqttQos.atLeastOnce, uint8buffer, retain: false);
  }

  int publishRawMessage(String pTopic, List<int> list) {
    typed.Uint8Buffer uint8buffer = typed.Uint8Buffer();
    uint8buffer.addAll(list);
    return mqttClient.publishMessage(pTopic, MqttQos.atLeastOnce, uint8buffer, retain: false);
  }

  // 连接成功
  void onConnected() {
    connectSate = ConnectState.connected;

    dPrint('Connected------------');
    if(null != callBack){
      callBack.onConnected();
    }

  }

// 连接断开
  void onDisconnected() {
    connectSate = ConnectState.disconnected;
    dPrint('Disconnected------------------');
    if(null != callBack){
      callBack.onDisconnected();
    }
  }

// 订阅主题成功
  void onSubscribed(String topic) {
    dPrint('Subscribed topic: $topic');
    if(null != callBack){
      callBack.onSubscribed(topic);
    }
  }

// 订阅主题失败
  void onSubscribeFail(String topic) {
    dPrint('Failed to subscribe $topic');
    if(null != callBack){
      callBack.onSubscribeFail(topic);
    }
  }

// 成功取消订阅
  void onUnsubscribed(String? topic) {
    dPrint('Unsubscribed topic: $topic');
    if(null != callBack){
      callBack.onUnsubscribed(topic!);
    }
  }

// 收到 PING 响应
  void pong() {
    dPrint('mqtt pong-------------');
    if(null != callBack){
      callBack.pong();
    }
  }

  bool debug = false;
  void dPrint(String msg){
    if(debug) debugPrint(msg);
  }
  
}